package com.zlh.rm.Exception.Dao;

import java.io.PrintStream;
import java.io.PrintWriter;

import com.zlh.rm.Exception.ErrorCode;
import com.zlh.rm.common.util.ThrowableFormatter;

public class SystemException extends RuntimeException {
    /**
     * error code.
     */
    private ErrorCode errorCode;
    /**
     * message parameters.
     */
    private Object[] messageParams;
    /**
     * localized message.
     */
    private String localizedMessage;

    /**
     * @param code
     *            error code
     */
    public SystemException(ErrorCode code) {
        this(code, null);
    }

    /**
     * @param cause
     *            exception cause
     * @param code
     *            error code
     */
    public SystemException(Throwable cause, ErrorCode code) {
        this(cause, code, null);
    }

    /**
     * @param message
     *            error message
     * @param code
     *            error code
     */
    public SystemException(String message, ErrorCode code) {
        this(message, code, null);
    }

    /**
     * @param code
     *            error code
     * @param params
     *            message parameters
     */
    public SystemException(ErrorCode code, Object... params) {
        super();
        this.errorCode = code;
        this.messageParams = params;
    }

    /**
     * @param cause
     *            exception cause
     * @param code
     *            error code
     * @param params
     *            message parameters
     */
    public SystemException(Throwable cause, ErrorCode code, Object... params) {
        super(cause);
        this.errorCode = code;
        this.messageParams = params;
    }

    /**
     * @param message
     *            error message
     * @param code
     *            error code
     * @param params
     *            message parameters
     */
    public SystemException(String message, ErrorCode code, Object... params) {
        super(message);
        this.errorCode = code;
        this.messageParams = params;
    }

    /**
     * @param message
     *            error message
     * @param code
     *            error code
     * @param cause
     *            exception cause
     * @param params
     *            message parameters
     */
    public SystemException(String message, ErrorCode code, Throwable cause,
            Object... params) {
        super(message, cause);
        this.messageParams = params;
        this.errorCode = code;
    }

    /**
     * wrap exception to SystemException.
     * @param exception
     *            the exception to wrap
     * @param errorCode
     *            error code
     * @return wrapped exception
     */
    public static SystemException wrap(Throwable exception, ErrorCode errorCode) {
        if (exception instanceof SystemException) {
            SystemException se = (SystemException) exception;
            if (errorCode != null && errorCode != se.getErrorCode()) {
                return new SystemException(errorCode, exception.getMessage(),
                        exception);
            }
            return se;
        } else {
            return new SystemException(errorCode, exception.getMessage(),
                    exception);
        }
    }

    @Override
    public String getMessage() {
        if (getErrorCode() != null) {
            if (super.getMessage() != null) {
                return ((Enum) getErrorCode()).name() + ":"
                        + super.getMessage();
            } else {
                return ((Enum) getErrorCode()).name();
            }
        }
        return super.getMessage();
    }

    @Override
    public String getLocalizedMessage() {
        if (localizedMessage == null) {
            return getMessage();
        }
        return localizedMessage;
    }

    /**
     * @param localizedMessage
     *            localized message
     */
    public void setLocalizedMessage(String localizedMessage) {
        this.localizedMessage = localizedMessage;
    }

    /**
     * get message pattern.
     * @return message name pattern.
     */
    public String getMessagePatten() {
        if (getErrorCode() != null) {
            return getErrorCode().getClass().getSimpleName() + "_"
                    + getErrorCode().getNumber();
        }
        return getMessage();
    }

    @Override
    public void printStackTrace(PrintStream s) {
        synchronized (s) {
            printStackTrace(new PrintWriter(s));
        }
    }

    @Override
    public void printStackTrace(PrintWriter s) {
        synchronized (s) {
            s.println(ThrowableFormatter.format(this, "com.inspur.ics"));
        }
    }

    /**
     * @return the errorCode
     */
    public ErrorCode getErrorCode() {
        return errorCode;
    }

    /**
     * @param errorCode
     *            the errorCode to set
     */
    public void setErrorCode(ErrorCode errorCode) {
        this.errorCode = errorCode;
    }

    /**
     * @return the messageParams
     */
    public Object[] getMessageParams() {
        return messageParams;
    }

    /**
     * @param messageParams
     *            the messageParams to set
     */
    public void setMessageParams(Object[] messageParams) {
        this.messageParams = messageParams;
    }
}
